//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension MemoryDB {
    // MARK: Enums

    public enum AZStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case multiAZ = "multiaz"
        case singleAZ = "singleaz"
        public var description: String { return self.rawValue }
    }

    public enum AuthenticationType: String, CustomStringConvertible, Codable, _SotoSendable {
        case noPassword = "no-password"
        case password
        public var description: String { return self.rawValue }
    }

    public enum DataTieringStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case `false`
        case `true`
        public var description: String { return self.rawValue }
    }

    public enum InputAuthenticationType: String, CustomStringConvertible, Codable, _SotoSendable {
        case password
        public var description: String { return self.rawValue }
    }

    public enum ServiceUpdateStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case complete
        case inProgress = "in-progress"
        case notApplied = "available"
        case scheduled
        public var description: String { return self.rawValue }
    }

    public enum ServiceUpdateType: String, CustomStringConvertible, Codable, _SotoSendable {
        case securityUpdate = "security-update"
        public var description: String { return self.rawValue }
    }

    public enum SourceType: String, CustomStringConvertible, Codable, _SotoSendable {
        case acl
        case cluster
        case node
        case parameterGroup = "parameter-group"
        case subnetGroup = "subnet-group"
        case user
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ACL: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the ACL
        public let arn: String?
        /// A list of clusters associated with the ACL.
        public let clusters: [String]?
        /// The minimum engine version supported for the ACL
        public let minimumEngineVersion: String?
        /// The name of the Access Control List
        public let name: String?
        /// A list of updates being applied to the ACL.
        public let pendingChanges: ACLPendingChanges?
        /// Indicates ACL status. Can be "creating", "active", "modifying", "deleting".
        public let status: String?
        /// The list of user names that belong to the ACL.
        public let userNames: [String]?

        public init(arn: String? = nil, clusters: [String]? = nil, minimumEngineVersion: String? = nil, name: String? = nil, pendingChanges: ACLPendingChanges? = nil, status: String? = nil, userNames: [String]? = nil) {
            self.arn = arn
            self.clusters = clusters
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.pendingChanges = pendingChanges
            self.status = status
            self.userNames = userNames
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusters = "Clusters"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case pendingChanges = "PendingChanges"
            case status = "Status"
            case userNames = "UserNames"
        }
    }

    public struct ACLPendingChanges: AWSDecodableShape {
        /// A list of users being added to the ACL
        public let userNamesToAdd: [String]?
        /// A list of user names being removed from the ACL
        public let userNamesToRemove: [String]?

        public init(userNamesToAdd: [String]? = nil, userNamesToRemove: [String]? = nil) {
            self.userNamesToAdd = userNamesToAdd
            self.userNamesToRemove = userNamesToRemove
        }

        private enum CodingKeys: String, CodingKey {
            case userNamesToAdd = "UserNamesToAdd"
            case userNamesToRemove = "UserNamesToRemove"
        }
    }

    public struct ACLsUpdateStatus: AWSDecodableShape {
        /// A list of ACLs pending to be applied.
        public let aclToApply: String?

        public init(aclToApply: String? = nil) {
            self.aclToApply = aclToApply
        }

        private enum CodingKeys: String, CodingKey {
            case aclToApply = "ACLToApply"
        }
    }

    public struct Authentication: AWSDecodableShape {
        /// The number of passwords belonging to the user. The maximum is two.
        public let passwordCount: Int?
        /// Indicates whether the user requires a password to authenticate.
        public let type: AuthenticationType?

        public init(passwordCount: Int? = nil, type: AuthenticationType? = nil) {
            self.passwordCount = passwordCount
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case passwordCount = "PasswordCount"
            case type = "Type"
        }
    }

    public struct AuthenticationMode: AWSEncodableShape {
        /// The password(s) used for authentication
        public let passwords: [String]?
        /// Indicates whether the user requires a password to authenticate. All newly-created users require a password.
        public let type: InputAuthenticationType?

        public init(passwords: [String]? = nil, type: InputAuthenticationType? = nil) {
            self.passwords = passwords
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.passwords, name: "passwords", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case passwords = "Passwords"
            case type = "Type"
        }
    }

    public struct AvailabilityZone: AWSDecodableShape {
        /// The name of the Availability Zone.
        public let name: String?

        public init(name: String? = nil) {
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
        }
    }

    public struct BatchUpdateClusterRequest: AWSEncodableShape {
        /// The cluster names to apply the updates.
        public let clusterNames: [String]
        /// The unique ID of the service update
        public let serviceUpdate: ServiceUpdateRequest?

        public init(clusterNames: [String], serviceUpdate: ServiceUpdateRequest? = nil) {
            self.clusterNames = clusterNames
            self.serviceUpdate = serviceUpdate
        }

        public func validate(name: String) throws {
            try self.validate(self.clusterNames, name: "clusterNames", parent: name, max: 20)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterNames = "ClusterNames"
            case serviceUpdate = "ServiceUpdate"
        }
    }

    public struct BatchUpdateClusterResponse: AWSDecodableShape {
        /// The list of clusters that have been updated.
        public let processedClusters: [Cluster]?
        /// The list of clusters where updates have not been applied.
        public let unprocessedClusters: [UnprocessedCluster]?

        public init(processedClusters: [Cluster]? = nil, unprocessedClusters: [UnprocessedCluster]? = nil) {
            self.processedClusters = processedClusters
            self.unprocessedClusters = unprocessedClusters
        }

        private enum CodingKeys: String, CodingKey {
            case processedClusters = "ProcessedClusters"
            case unprocessedClusters = "UnprocessedClusters"
        }
    }

    public struct Cluster: AWSDecodableShape {
        /// The name of the Access Control List associated with this cluster.
        public let aclName: String?
        /// The Amazon Resource Name (ARN) of the cluster.
        public let arn: String?
        /// When set to true, the cluster will automatically receive minor engine version upgrades after launch.
        public let autoMinorVersionUpgrade: Bool?
        /// Indicates if the cluster has a Multi-AZ configuration (multiaz) or not (singleaz).
        public let availabilityMode: AZStatus?
        /// The cluster's configuration endpoint
        public let clusterEndpoint: Endpoint?
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: DataTieringStatus?
        /// A description of the cluster
        public let description: String?
        /// The Redis engine patch version used by the cluster
        public let enginePatchVersion: String?
        /// The Redis engine version used by the cluster
        public let engineVersion: String?
        /// The ID of the KMS key used to encrypt the cluster
        public let kmsKeyId: String?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period.
        public let maintenanceWindow: String?
        /// The user-supplied name of the cluster. This identifier is a unique key that identifies a cluster.
        public let name: String?
        /// The cluster's node type
        public let nodeType: String?
        /// The number of shards in the cluster
        public let numberOfShards: Int?
        /// The name of the parameter group used by the cluster
        public let parameterGroupName: String?
        /// The status of the parameter group used by the cluster, for example 'active' or 'applying'.
        public let parameterGroupStatus: String?
        /// A group of settings that are currently being applied.
        public let pendingUpdates: ClusterPendingUpdates?
        /// A list of security groups used by the cluster
        public let securityGroups: [SecurityGroupMembership]?
        /// A list of shards that are members of the cluster.
        public let shards: [Shard]?
        /// The number of days for which MemoryDB retains automatic snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your shard.  Example: 05:00-09:00  If you do not specify this parameter, MemoryDB automatically chooses an appropriate time range.
        public let snapshotWindow: String?
        /// The Amazon Resource Name (ARN) of the SNS notification topic
        public let snsTopicArn: String?
        /// The SNS topic must be in Active status to receive notifications
        public let snsTopicStatus: String?
        /// The status of the cluster. For example, Available, Updating, Creating.
        public let status: String?
        /// The name of the subnet group used by the cluster
        public let subnetGroupName: String?
        /// A flag to indicate if In-transit encryption is enabled
        public let tlsEnabled: Bool?

        public init(aclName: String? = nil, arn: String? = nil, autoMinorVersionUpgrade: Bool? = nil, availabilityMode: AZStatus? = nil, clusterEndpoint: Endpoint? = nil, dataTiering: DataTieringStatus? = nil, description: String? = nil, enginePatchVersion: String? = nil, engineVersion: String? = nil, kmsKeyId: String? = nil, maintenanceWindow: String? = nil, name: String? = nil, nodeType: String? = nil, numberOfShards: Int? = nil, parameterGroupName: String? = nil, parameterGroupStatus: String? = nil, pendingUpdates: ClusterPendingUpdates? = nil, securityGroups: [SecurityGroupMembership]? = nil, shards: [Shard]? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, snsTopicStatus: String? = nil, status: String? = nil, subnetGroupName: String? = nil, tlsEnabled: Bool? = nil) {
            self.aclName = aclName
            self.arn = arn
            self.autoMinorVersionUpgrade = autoMinorVersionUpgrade
            self.availabilityMode = availabilityMode
            self.clusterEndpoint = clusterEndpoint
            self.dataTiering = dataTiering
            self.description = description
            self.enginePatchVersion = enginePatchVersion
            self.engineVersion = engineVersion
            self.kmsKeyId = kmsKeyId
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.nodeType = nodeType
            self.numberOfShards = numberOfShards
            self.parameterGroupName = parameterGroupName
            self.parameterGroupStatus = parameterGroupStatus
            self.pendingUpdates = pendingUpdates
            self.securityGroups = securityGroups
            self.shards = shards
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.snsTopicStatus = snsTopicStatus
            self.status = status
            self.subnetGroupName = subnetGroupName
            self.tlsEnabled = tlsEnabled
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case arn = "ARN"
            case autoMinorVersionUpgrade = "AutoMinorVersionUpgrade"
            case availabilityMode = "AvailabilityMode"
            case clusterEndpoint = "ClusterEndpoint"
            case dataTiering = "DataTiering"
            case description = "Description"
            case enginePatchVersion = "EnginePatchVersion"
            case engineVersion = "EngineVersion"
            case kmsKeyId = "KmsKeyId"
            case maintenanceWindow = "MaintenanceWindow"
            case name = "Name"
            case nodeType = "NodeType"
            case numberOfShards = "NumberOfShards"
            case parameterGroupName = "ParameterGroupName"
            case parameterGroupStatus = "ParameterGroupStatus"
            case pendingUpdates = "PendingUpdates"
            case securityGroups = "SecurityGroups"
            case shards = "Shards"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case snsTopicStatus = "SnsTopicStatus"
            case status = "Status"
            case subnetGroupName = "SubnetGroupName"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct ClusterConfiguration: AWSDecodableShape {
        /// The description of the cluster configuration
        public let description: String?
        /// The Redis engine version used by the cluster
        public let engineVersion: String?
        /// The specified maintenance window for the cluster
        public let maintenanceWindow: String?
        /// The name of the cluster
        public let name: String?
        /// The node type used for the cluster
        public let nodeType: String?
        /// The number of shards in the cluster
        public let numShards: Int?
        /// The name of parameter group used by the cluster
        public let parameterGroupName: String?
        /// The port used by the cluster
        public let port: Int?
        /// The list of shards in the cluster
        public let shards: [ShardDetail]?
        /// The snapshot retention limit set by the cluster
        public let snapshotRetentionLimit: Int?
        /// The snapshot window set by the cluster
        public let snapshotWindow: String?
        /// The name of the subnet group used by the cluster
        public let subnetGroupName: String?
        /// The Amazon Resource Name (ARN) of the SNS notification topic for the cluster
        public let topicArn: String?
        /// The ID of the VPC the cluster belongs to
        public let vpcId: String?

        public init(description: String? = nil, engineVersion: String? = nil, maintenanceWindow: String? = nil, name: String? = nil, nodeType: String? = nil, numShards: Int? = nil, parameterGroupName: String? = nil, port: Int? = nil, shards: [ShardDetail]? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, subnetGroupName: String? = nil, topicArn: String? = nil, vpcId: String? = nil) {
            self.description = description
            self.engineVersion = engineVersion
            self.maintenanceWindow = maintenanceWindow
            self.name = name
            self.nodeType = nodeType
            self.numShards = numShards
            self.parameterGroupName = parameterGroupName
            self.port = port
            self.shards = shards
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.subnetGroupName = subnetGroupName
            self.topicArn = topicArn
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case engineVersion = "EngineVersion"
            case maintenanceWindow = "MaintenanceWindow"
            case name = "Name"
            case nodeType = "NodeType"
            case numShards = "NumShards"
            case parameterGroupName = "ParameterGroupName"
            case port = "Port"
            case shards = "Shards"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case subnetGroupName = "SubnetGroupName"
            case topicArn = "TopicArn"
            case vpcId = "VpcId"
        }
    }

    public struct ClusterPendingUpdates: AWSDecodableShape {
        /// A list of ACLs associated with the cluster that are being updated
        public let acLs: ACLsUpdateStatus?
        /// The status of an online resharding operation.
        public let resharding: ReshardingStatus?
        /// A list of service updates being applied to the cluster
        public let serviceUpdates: [PendingModifiedServiceUpdate]?

        public init(acLs: ACLsUpdateStatus? = nil, resharding: ReshardingStatus? = nil, serviceUpdates: [PendingModifiedServiceUpdate]? = nil) {
            self.acLs = acLs
            self.resharding = resharding
            self.serviceUpdates = serviceUpdates
        }

        private enum CodingKeys: String, CodingKey {
            case acLs = "ACLs"
            case resharding = "Resharding"
            case serviceUpdates = "ServiceUpdates"
        }
    }

    public struct CopySnapshotRequest: AWSEncodableShape {
        /// The ID of the KMS key used to encrypt the target snapshot.
        public let kmsKeyId: String?
        /// The name of an existing snapshot from which to make a copy.
        public let sourceSnapshotName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The Amazon S3 bucket to which the snapshot is exported. This parameter is used only when exporting a snapshot for external access.  When using this parameter to export a snapshot, be sure MemoryDB has the needed permissions to this S3 bucket. For more information, see   Step 2: Grant MemoryDB Access to Your Amazon S3 Bucket.
        public let targetBucket: String?
        /// A name for the snapshot copy. MemoryDB does not permit overwriting a snapshot, therefore this name must be unique within its context - MemoryDB or an Amazon S3 bucket if exporting.
        public let targetSnapshotName: String

        public init(kmsKeyId: String? = nil, sourceSnapshotName: String, tags: [Tag]? = nil, targetBucket: String? = nil, targetSnapshotName: String) {
            self.kmsKeyId = kmsKeyId
            self.sourceSnapshotName = sourceSnapshotName
            self.tags = tags
            self.targetBucket = targetBucket
            self.targetSnapshotName = targetSnapshotName
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 2048)
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.targetBucket, name: "targetBucket", parent: name, max: 255)
            try self.validate(self.targetBucket, name: "targetBucket", parent: name, pattern: "^[A-Za-z0-9._-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyId = "KmsKeyId"
            case sourceSnapshotName = "SourceSnapshotName"
            case tags = "Tags"
            case targetBucket = "TargetBucket"
            case targetSnapshotName = "TargetSnapshotName"
        }
    }

    public struct CopySnapshotResponse: AWSDecodableShape {
        /// Represents a copy of an entire cluster as of the time when the snapshot was taken.
        public let snapshot: Snapshot?

        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct CreateACLRequest: AWSEncodableShape {
        /// The name of the Access Control List.
        public let aclName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The list of users that belong to the Access Control List.
        public let userNames: [String]?

        public init(aclName: String, tags: [Tag]? = nil, userNames: [String]? = nil) {
            self.aclName = aclName
            self.tags = tags
            self.userNames = userNames
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.userNames?.forEach {
                try validate($0, name: "userNames[]", parent: name, min: 1)
                try validate($0, name: "userNames[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNames, name: "userNames", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case tags = "Tags"
            case userNames = "UserNames"
        }
    }

    public struct CreateACLResponse: AWSDecodableShape {
        /// The newly-created Access Control List.
        public let acl: ACL?

        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct CreateClusterRequest: AWSEncodableShape {
        /// The name of the Access Control List to associate with the cluster.
        public let aclName: String
        /// When set to true, the cluster will automatically receive minor engine version upgrades after launch.
        public let autoMinorVersionUpgrade: Bool?
        /// The name of the cluster. This value must be unique as it also serves as the cluster identifier.
        public let clusterName: String
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: Bool?
        /// An optional description of the cluster.
        public let description: String?
        /// The version number of the Redis engine to be used for the cluster.
        public let engineVersion: String?
        /// The ID of the KMS key used to encrypt the cluster.
        public let kmsKeyId: String?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:    sun     mon     tue     wed     thu     fri     sat    Example: sun:23:00-mon:01:30
        public let maintenanceWindow: String?
        /// The compute and memory capacity of the nodes in the cluster.
        public let nodeType: String
        /// The number of replicas to apply to each shard. The default value is 1. The maximum is 5.
        public let numReplicasPerShard: Int?
        /// The number of shards the cluster will contain. The default value is 1.
        public let numShards: Int?
        /// The name of the parameter group associated with the cluster.
        public let parameterGroupName: String?
        /// The port number on which each of the nodes accepts connections.
        public let port: Int?
        /// A list of security group names to associate with this cluster.
        public let securityGroupIds: [String]?
        /// A list of Amazon Resource Names (ARN) that uniquely identify the RDB snapshot files stored in Amazon S3. The snapshot files are used to populate the new cluster. The Amazon S3 object name in the ARN cannot contain any commas.
        public let snapshotArns: [String]?
        /// The name of a snapshot from which to restore data into the new cluster. The snapshot status changes to restoring while the new cluster is being created.
        public let snapshotName: String?
        /// The number of days for which MemoryDB retains automatic snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your shard. Example: 05:00-09:00 If you do not specify this parameter, MemoryDB automatically chooses an appropriate time range.
        public let snapshotWindow: String?
        /// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service (SNS) topic to which notifications are sent.
        public let snsTopicArn: String?
        /// The name of the subnet group to be used for the cluster.
        public let subnetGroupName: String?
        /// A list of tags to be added to this resource. Tags are comma-separated key,value pairs (e.g. Key=myKey, Value=myKeyValue. You can include multiple tags as shown following: Key=myKey, Value=myKeyValue Key=mySecondKey, Value=mySecondKeyValue.
        public let tags: [Tag]?
        /// A flag to enable in-transit encryption on the cluster.
        public let tlsEnabled: Bool?

        public init(aclName: String, autoMinorVersionUpgrade: Bool? = nil, clusterName: String, dataTiering: Bool? = nil, description: String? = nil, engineVersion: String? = nil, kmsKeyId: String? = nil, maintenanceWindow: String? = nil, nodeType: String, numReplicasPerShard: Int? = nil, numShards: Int? = nil, parameterGroupName: String? = nil, port: Int? = nil, securityGroupIds: [String]? = nil, snapshotArns: [String]? = nil, snapshotName: String? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, subnetGroupName: String? = nil, tags: [Tag]? = nil, tlsEnabled: Bool? = nil) {
            self.aclName = aclName
            self.autoMinorVersionUpgrade = autoMinorVersionUpgrade
            self.clusterName = clusterName
            self.dataTiering = dataTiering
            self.description = description
            self.engineVersion = engineVersion
            self.kmsKeyId = kmsKeyId
            self.maintenanceWindow = maintenanceWindow
            self.nodeType = nodeType
            self.numReplicasPerShard = numReplicasPerShard
            self.numShards = numShards
            self.parameterGroupName = parameterGroupName
            self.port = port
            self.securityGroupIds = securityGroupIds
            self.snapshotArns = snapshotArns
            self.snapshotName = snapshotName
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.subnetGroupName = subnetGroupName
            self.tags = tags
            self.tlsEnabled = tlsEnabled
        }

        public func validate(name: String) throws {
            try self.validate(self.aclName, name: "aclName", parent: name, min: 1)
            try self.validate(self.aclName, name: "aclName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case autoMinorVersionUpgrade = "AutoMinorVersionUpgrade"
            case clusterName = "ClusterName"
            case dataTiering = "DataTiering"
            case description = "Description"
            case engineVersion = "EngineVersion"
            case kmsKeyId = "KmsKeyId"
            case maintenanceWindow = "MaintenanceWindow"
            case nodeType = "NodeType"
            case numReplicasPerShard = "NumReplicasPerShard"
            case numShards = "NumShards"
            case parameterGroupName = "ParameterGroupName"
            case port = "Port"
            case securityGroupIds = "SecurityGroupIds"
            case snapshotArns = "SnapshotArns"
            case snapshotName = "SnapshotName"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case subnetGroupName = "SubnetGroupName"
            case tags = "Tags"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct CreateClusterResponse: AWSDecodableShape {
        /// The newly-created cluster.
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct CreateParameterGroupRequest: AWSEncodableShape {
        /// An optional description of the parameter group.
        public let description: String?
        /// The name of the parameter group family that the parameter group can be used with.
        public let family: String
        /// The name of the parameter group.
        public let parameterGroupName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        public init(description: String? = nil, family: String, parameterGroupName: String, tags: [Tag]? = nil) {
            self.description = description
            self.family = family
            self.parameterGroupName = parameterGroupName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case family = "Family"
            case parameterGroupName = "ParameterGroupName"
            case tags = "Tags"
        }
    }

    public struct CreateParameterGroupResponse: AWSDecodableShape {
        /// The newly-created parameter group.
        public let parameterGroup: ParameterGroup?

        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct CreateSnapshotRequest: AWSEncodableShape {
        /// The snapshot is created from this cluster.
        public let clusterName: String
        /// The ID of the KMS key used to encrypt the snapshot.
        public let kmsKeyId: String?
        /// A name for the snapshot being created.
        public let snapshotName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        public init(clusterName: String, kmsKeyId: String? = nil, snapshotName: String, tags: [Tag]? = nil) {
            self.clusterName = clusterName
            self.kmsKeyId = kmsKeyId
            self.snapshotName = snapshotName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case kmsKeyId = "KmsKeyId"
            case snapshotName = "SnapshotName"
            case tags = "Tags"
        }
    }

    public struct CreateSnapshotResponse: AWSDecodableShape {
        /// The newly-created snapshot.
        public let snapshot: Snapshot?

        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct CreateSubnetGroupRequest: AWSEncodableShape {
        /// A description for the subnet group.
        public let description: String?
        /// The name of the subnet group.
        public let subnetGroupName: String
        /// A list of VPC subnet IDs for the subnet group.
        public let subnetIds: [String]
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String], tags: [Tag]? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
            case tags = "Tags"
        }
    }

    public struct CreateSubnetGroupResponse: AWSDecodableShape {
        /// The newly-created subnet group
        public let subnetGroup: SubnetGroup?

        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct CreateUserRequest: AWSEncodableShape {
        /// Access permissions string used for this user.
        public let accessString: String
        /// Denotes the user's authentication properties, such as whether it requires a password to authenticate.
        public let authenticationMode: AuthenticationMode
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The name of the user. This value must be unique as it also serves as the user identifier.
        public let userName: String

        public init(accessString: String, authenticationMode: AuthenticationMode, tags: [Tag]? = nil, userName: String) {
            self.accessString = accessString
            self.authenticationMode = authenticationMode
            self.tags = tags
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.accessString, name: "accessString", parent: name, pattern: "\\S")
            try self.authenticationMode.validate(name: "\(name).authenticationMode")
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case authenticationMode = "AuthenticationMode"
            case tags = "Tags"
            case userName = "UserName"
        }
    }

    public struct CreateUserResponse: AWSDecodableShape {
        /// The newly-created user.
        public let user: User?

        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct DeleteACLRequest: AWSEncodableShape {
        /// The name of the Access Control List to delete
        public let aclName: String

        public init(aclName: String) {
            self.aclName = aclName
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
        }
    }

    public struct DeleteACLResponse: AWSDecodableShape {
        /// The Access Control List object that has been deleted.
        public let acl: ACL?

        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct DeleteClusterRequest: AWSEncodableShape {
        /// The name of the cluster to be deleted
        public let clusterName: String
        /// The user-supplied name of a final cluster snapshot. This is the unique name that identifies the snapshot. MemoryDB creates the snapshot, and then deletes the cluster immediately afterward.
        public let finalSnapshotName: String?

        public init(clusterName: String, finalSnapshotName: String? = nil) {
            self.clusterName = clusterName
            self.finalSnapshotName = finalSnapshotName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case finalSnapshotName = "FinalSnapshotName"
        }
    }

    public struct DeleteClusterResponse: AWSDecodableShape {
        /// The cluster object that has been deleted
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct DeleteParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group to delete.
        public let parameterGroupName: String

        public init(parameterGroupName: String) {
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DeleteParameterGroupResponse: AWSDecodableShape {
        /// The parameter group that has been deleted.
        public let parameterGroup: ParameterGroup?

        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct DeleteSnapshotRequest: AWSEncodableShape {
        /// The name of the snapshot to delete
        public let snapshotName: String

        public init(snapshotName: String) {
            self.snapshotName = snapshotName
        }

        private enum CodingKeys: String, CodingKey {
            case snapshotName = "SnapshotName"
        }
    }

    public struct DeleteSnapshotResponse: AWSDecodableShape {
        /// The snapshot object that has been deleted.
        public let snapshot: Snapshot?

        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct DeleteSubnetGroupRequest: AWSEncodableShape {
        /// The name of the subnet group to delete
        public let subnetGroupName: String

        public init(subnetGroupName: String) {
            self.subnetGroupName = subnetGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroupName = "SubnetGroupName"
        }
    }

    public struct DeleteSubnetGroupResponse: AWSDecodableShape {
        /// The subnet group object that has been deleted.
        public let subnetGroup: SubnetGroup?

        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct DeleteUserRequest: AWSEncodableShape {
        /// The name of the user to delete
        public let userName: String

        public init(userName: String) {
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case userName = "UserName"
        }
    }

    public struct DeleteUserResponse: AWSDecodableShape {
        /// The user object that has been deleted.
        public let user: User?

        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct DescribeACLsRequest: AWSEncodableShape {
        /// The name of the ACL
        public let aclName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        public init(aclName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.aclName = aclName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeACLsResponse: AWSDecodableShape {
        /// The list of ACLs
        public let acLs: [ACL]?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        public init(acLs: [ACL]? = nil, nextToken: String? = nil) {
            self.acLs = acLs
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case acLs = "ACLs"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeClustersRequest: AWSEncodableShape {
        /// The name of the cluster
        public let clusterName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// An optional flag that can be included in the request to retrieve information about the individual shard(s).
        public let showShardDetails: Bool?

        public init(clusterName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, showShardDetails: Bool? = nil) {
            self.clusterName = clusterName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.showShardDetails = showShardDetails
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case showShardDetails = "ShowShardDetails"
        }
    }

    public struct DescribeClustersResponse: AWSDecodableShape {
        /// A list of clusters
        public let clusters: [Cluster]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        public init(clusters: [Cluster]? = nil, nextToken: String? = nil) {
            self.clusters = clusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusters = "Clusters"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeEngineVersionsRequest: AWSEncodableShape {
        /// If true, specifies that only the default version of the specified engine or engine and major version combination is to be returned.
        public let defaultOnly: Bool?
        /// The Redis engine version
        public let engineVersion: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of a specific parameter group family to return details for.
        public let parameterGroupFamily: String?

        public init(defaultOnly: Bool? = nil, engineVersion: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, parameterGroupFamily: String? = nil) {
            self.defaultOnly = defaultOnly
            self.engineVersion = engineVersion
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupFamily = parameterGroupFamily
        }

        private enum CodingKeys: String, CodingKey {
            case defaultOnly = "DefaultOnly"
            case engineVersion = "EngineVersion"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupFamily = "ParameterGroupFamily"
        }
    }

    public struct DescribeEngineVersionsResponse: AWSDecodableShape {
        /// A list of engine version details. Each element in the list contains detailed information about one engine version.
        public let engineVersions: [EngineVersionInfo]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        public init(engineVersions: [EngineVersionInfo]? = nil, nextToken: String? = nil) {
            self.engineVersions = engineVersions
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case engineVersions = "EngineVersions"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeEventsRequest: AWSEncodableShape {
        /// The number of minutes worth of events to retrieve.
        public let duration: Int?
        /// The end of the time interval for which to retrieve events, specified in ISO 8601 format.  Example: 2017-03-30T07:03:49.555Z
        public let endTime: Date?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The identifier of the event source for which events are returned. If not specified, all sources are included in the response.
        public let sourceName: String?
        /// The event source to retrieve events for. If no value is specified, all events are returned.
        public let sourceType: SourceType?
        /// The beginning of the time interval to retrieve events for, specified in ISO 8601 format.  Example: 2017-03-30T07:03:49.555Z
        public let startTime: Date?

        public init(duration: Int? = nil, endTime: Date? = nil, maxResults: Int? = nil, nextToken: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil, startTime: Date? = nil) {
            self.duration = duration
            self.endTime = endTime
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.sourceName = sourceName
            self.sourceType = sourceType
            self.startTime = startTime
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case endTime = "EndTime"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
            case startTime = "StartTime"
        }
    }

    public struct DescribeEventsResponse: AWSDecodableShape {
        /// A list of events. Each element in the list contains detailed information about one event.
        public let events: [Event]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        public init(events: [Event]? = nil, nextToken: String? = nil) {
            self.events = events
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case events = "Events"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeParameterGroupsRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of a specific  parameter group to return details for.
        public let parameterGroupName: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DescribeParameterGroupsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of parameter groups. Each element in the list contains detailed information about one parameter group.
        public let parameterGroups: [ParameterGroup]?

        public init(nextToken: String? = nil, parameterGroups: [ParameterGroup]? = nil) {
            self.nextToken = nextToken
            self.parameterGroups = parameterGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameterGroups = "ParameterGroups"
        }
    }

    public struct DescribeParametersRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// he name of a specific  parameter group to return details for.
        public let parameterGroupName: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupName: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DescribeParametersResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of parameters specific to a particular parameter group. Each element in the list contains detailed information about one parameter.
        public let parameters: [Parameter]?

        public init(nextToken: String? = nil, parameters: [Parameter]? = nil) {
            self.nextToken = nextToken
            self.parameters = parameters
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameters = "Parameters"
        }
    }

    public struct DescribeReservedNodesOfferingsRequest: AWSEncodableShape {
        /// Duration filter value, specified in years or seconds. Use this parameter to show only reservations for a given duration.
        public let duration: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a marker is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// The node type for the reserved nodes. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type filter value. Use this parameter to show only the available offerings matching the specified offering type.  Valid values: "All Upfront"|"Partial Upfront"| "No Upfront"
        public let offeringType: String?
        /// The offering identifier filter value. Use this parameter to show only the available offering that matches the specified reservation identifier.
        public let reservedNodesOfferingId: String?

        public init(duration: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, nodeType: String? = nil, offeringType: String? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct DescribeReservedNodesOfferingsResponse: AWSDecodableShape {
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// Lists available reserved node offerings.
        public let reservedNodesOfferings: [ReservedNodesOffering]?

        public init(nextToken: String? = nil, reservedNodesOfferings: [ReservedNodesOffering]? = nil) {
            self.nextToken = nextToken
            self.reservedNodesOfferings = reservedNodesOfferings
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case reservedNodesOfferings = "ReservedNodesOfferings"
        }
    }

    public struct DescribeReservedNodesRequest: AWSEncodableShape {
        /// The duration filter value, specified in years or seconds. Use this parameter to show only reservations for this duration.
        public let duration: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a marker is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// The node type filter value. Use this parameter to show only those reservations matching the specified  node type. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type filter value. Use this parameter to show only the available offerings matching the specified offering type.  Valid values: "All Upfront"|"Partial Upfront"| "No Upfront"
        public let offeringType: String?
        /// The reserved node identifier filter value. Use this parameter to show only the reservation that matches the specified reservation ID.
        public let reservationId: String?
        /// The offering identifier filter value. Use this parameter to show only purchased reservations matching the specified offering identifier.
        public let reservedNodesOfferingId: String?

        public init(duration: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, nodeType: String? = nil, offeringType: String? = nil, reservationId: String? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct DescribeReservedNodesResponse: AWSDecodableShape {
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// Returns information about reserved nodes for this account, or about a specified reserved node.
        public let reservedNodes: [ReservedNode]?

        public init(nextToken: String? = nil, reservedNodes: [ReservedNode]? = nil) {
            self.nextToken = nextToken
            self.reservedNodes = reservedNodes
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case reservedNodes = "ReservedNodes"
        }
    }

    public struct DescribeServiceUpdatesRequest: AWSEncodableShape {
        /// The list of cluster names to identify service updates to apply
        public let clusterNames: [String]?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The unique ID of the service update to describe.
        public let serviceUpdateName: String?
        /// The status(es) of the service updates to filter on
        public let status: [ServiceUpdateStatus]?

        public init(clusterNames: [String]? = nil, maxResults: Int? = nil, nextToken: String? = nil, serviceUpdateName: String? = nil, status: [ServiceUpdateStatus]? = nil) {
            self.clusterNames = clusterNames
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serviceUpdateName = serviceUpdateName
            self.status = status
        }

        public func validate(name: String) throws {
            try self.validate(self.clusterNames, name: "clusterNames", parent: name, max: 20)
            try self.validate(self.status, name: "status", parent: name, max: 4)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterNames = "ClusterNames"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
        }
    }

    public struct DescribeServiceUpdatesResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of service updates
        public let serviceUpdates: [ServiceUpdate]?

        public init(nextToken: String? = nil, serviceUpdates: [ServiceUpdate]? = nil) {
            self.nextToken = nextToken
            self.serviceUpdates = serviceUpdates
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case serviceUpdates = "ServiceUpdates"
        }
    }

    public struct DescribeSnapshotsRequest: AWSEncodableShape {
        /// A user-supplied cluster identifier. If this parameter is specified, only snapshots associated with that specific cluster are described.
        public let clusterName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A Boolean value which if true, the shard configuration is included in the snapshot description.
        public let showDetail: Bool?
        /// A user-supplied name of the snapshot. If this parameter is specified, only this named snapshot is described.
        public let snapshotName: String?
        /// If set to system, the output shows snapshots that were automatically created by MemoryDB. If set to user the output shows snapshots that were manually created. If omitted, the output shows both automatically and manually created snapshots.
        public let source: String?

        public init(clusterName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, showDetail: Bool? = nil, snapshotName: String? = nil, source: String? = nil) {
            self.clusterName = clusterName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.showDetail = showDetail
            self.snapshotName = snapshotName
            self.source = source
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case showDetail = "ShowDetail"
            case snapshotName = "SnapshotName"
            case source = "Source"
        }
    }

    public struct DescribeSnapshotsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of snapshots. Each item in the list contains detailed information about one snapshot.
        public let snapshots: [Snapshot]?

        public init(nextToken: String? = nil, snapshots: [Snapshot]? = nil) {
            self.nextToken = nextToken
            self.snapshots = snapshots
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case snapshots = "Snapshots"
        }
    }

    public struct DescribeSubnetGroupsRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of the subnet group to return details for.
        public let subnetGroupName: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil, subnetGroupName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.subnetGroupName = subnetGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case subnetGroupName = "SubnetGroupName"
        }
    }

    public struct DescribeSubnetGroupsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of subnet groups. Each element in the list contains detailed information about one group.
        public let subnetGroups: [SubnetGroup]?

        public init(nextToken: String? = nil, subnetGroups: [SubnetGroup]? = nil) {
            self.nextToken = nextToken
            self.subnetGroups = subnetGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case subnetGroups = "SubnetGroups"
        }
    }

    public struct DescribeUsersRequest: AWSEncodableShape {
        /// Filter to determine the list of users to return.
        public let filters: [Filter]?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of the user
        public let userName: String?

        public init(filters: [Filter]? = nil, maxResults: Int? = nil, nextToken: String? = nil, userName: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.filters?.forEach {
                try $0.validate(name: "\(name).filters[]")
            }
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case filters = "Filters"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case userName = "UserName"
        }
    }

    public struct DescribeUsersResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of users.
        public let users: [User]?

        public init(nextToken: String? = nil, users: [User]? = nil) {
            self.nextToken = nextToken
            self.users = users
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case users = "Users"
        }
    }

    public struct Endpoint: AWSDecodableShape {
        /// The DNS hostname of the node.
        public let address: String?
        /// The port number that the engine is listening on.
        public let port: Int?

        public init(address: String? = nil, port: Int? = nil) {
            self.address = address
            self.port = port
        }

        private enum CodingKeys: String, CodingKey {
            case address = "Address"
            case port = "Port"
        }
    }

    public struct EngineVersionInfo: AWSDecodableShape {
        /// The patched engine version
        public let enginePatchVersion: String?
        /// The engine version
        public let engineVersion: String?
        /// Specifies the name of the parameter group family to which the engine default parameters apply.
        public let parameterGroupFamily: String?

        public init(enginePatchVersion: String? = nil, engineVersion: String? = nil, parameterGroupFamily: String? = nil) {
            self.enginePatchVersion = enginePatchVersion
            self.engineVersion = engineVersion
            self.parameterGroupFamily = parameterGroupFamily
        }

        private enum CodingKeys: String, CodingKey {
            case enginePatchVersion = "EnginePatchVersion"
            case engineVersion = "EngineVersion"
            case parameterGroupFamily = "ParameterGroupFamily"
        }
    }

    public struct Event: AWSDecodableShape {
        /// The date and time when the event occurred.
        public let date: Date?
        /// The text of the event.
        public let message: String?
        /// The name for the source of the event. For example, if the event occurred at the cluster level, the identifier would be the name of the cluster.
        public let sourceName: String?
        /// Specifies the origin of this event - a cluster, a parameter group, a security group, etc.
        public let sourceType: SourceType?

        public init(date: Date? = nil, message: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil) {
            self.date = date
            self.message = message
            self.sourceName = sourceName
            self.sourceType = sourceType
        }

        private enum CodingKeys: String, CodingKey {
            case date = "Date"
            case message = "Message"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
        }
    }

    public struct FailoverShardRequest: AWSEncodableShape {
        /// The cluster being failed over
        public let clusterName: String
        /// The name of the shard
        public let shardName: String

        public init(clusterName: String, shardName: String) {
            self.clusterName = clusterName
            self.shardName = shardName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case shardName = "ShardName"
        }
    }

    public struct FailoverShardResponse: AWSDecodableShape {
        /// The cluster being failed over
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct Filter: AWSEncodableShape {
        /// The property being filtered. For example, UserName.
        public let name: String
        /// The property values to filter on. For example, "user-123".
        public let values: [String]

        public init(name: String, values: [String]) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, pattern: "\\S")
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, pattern: "\\S")
            }
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case values = "Values"
        }
    }

    public struct ListAllowedNodeTypeUpdatesRequest: AWSEncodableShape {
        /// The name of the cluster you want to scale. MemoryDB uses the cluster name to identify the current node type being used by this cluster, and from that to create a list of node types you can scale up to.
        public let clusterName: String

        public init(clusterName: String) {
            self.clusterName = clusterName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
        }
    }

    public struct ListAllowedNodeTypeUpdatesResponse: AWSDecodableShape {
        /// A list node types which you can use to scale down your cluster.
        public let scaleDownNodeTypes: [String]?
        /// A list node types which you can use to scale up your cluster.
        public let scaleUpNodeTypes: [String]?

        public init(scaleDownNodeTypes: [String]? = nil, scaleUpNodeTypes: [String]? = nil) {
            self.scaleDownNodeTypes = scaleDownNodeTypes
            self.scaleUpNodeTypes = scaleUpNodeTypes
        }

        private enum CodingKeys: String, CodingKey {
            case scaleDownNodeTypes = "ScaleDownNodeTypes"
            case scaleUpNodeTypes = "ScaleUpNodeTypes"
        }
    }

    public struct ListTagsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource for which you want the list of tags
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsResponse: AWSDecodableShape {
        /// A list of tags as key-value pairs.
        public let tagList: [Tag]?

        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct Node: AWSDecodableShape {
        /// The Availability Zone in which the node resides
        public let availabilityZone: String?
        /// The date and time when the node was created.
        public let createTime: Date?
        /// The hostname for connecting to this node.
        public let endpoint: Endpoint?
        /// The  node identifier. A node name is a numeric identifier (0001, 0002, etc.). The combination of cluster name, shard name and node name uniquely identifies every node used in a customer's Amazon account.
        public let name: String?
        /// The status of the service update on the node
        public let status: String?

        public init(availabilityZone: String? = nil, createTime: Date? = nil, endpoint: Endpoint? = nil, name: String? = nil, status: String? = nil) {
            self.availabilityZone = availabilityZone
            self.createTime = createTime
            self.endpoint = endpoint
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case createTime = "CreateTime"
            case endpoint = "Endpoint"
            case name = "Name"
            case status = "Status"
        }
    }

    public struct Parameter: AWSDecodableShape {
        /// The valid range of values for the parameter.
        public let allowedValues: String?
        /// The parameter's data type
        public let dataType: String?
        /// A description of the parameter
        public let description: String?
        /// The earliest engine version to which the parameter can apply.
        public let minimumEngineVersion: String?
        /// The name of the parameter
        public let name: String?
        /// The value of the parameter
        public let value: String?

        public init(allowedValues: String? = nil, dataType: String? = nil, description: String? = nil, minimumEngineVersion: String? = nil, name: String? = nil, value: String? = nil) {
            self.allowedValues = allowedValues
            self.dataType = dataType
            self.description = description
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case allowedValues = "AllowedValues"
            case dataType = "DataType"
            case description = "Description"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case value = "Value"
        }
    }

    public struct ParameterGroup: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the parameter group
        public let arn: String?
        /// A description of the parameter group
        public let description: String?
        /// The name of the parameter group family that this  parameter group is compatible with.
        public let family: String?
        /// The name of the parameter group
        public let name: String?

        public init(arn: String? = nil, description: String? = nil, family: String? = nil, name: String? = nil) {
            self.arn = arn
            self.description = description
            self.family = family
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case description = "Description"
            case family = "Family"
            case name = "Name"
        }
    }

    public struct ParameterNameValue: AWSEncodableShape {
        /// The name of the parameter
        public let parameterName: String?
        /// The value of the parameter
        public let parameterValue: String?

        public init(parameterName: String? = nil, parameterValue: String? = nil) {
            self.parameterName = parameterName
            self.parameterValue = parameterValue
        }

        private enum CodingKeys: String, CodingKey {
            case parameterName = "ParameterName"
            case parameterValue = "ParameterValue"
        }
    }

    public struct PendingModifiedServiceUpdate: AWSDecodableShape {
        /// The unique ID of the service update
        public let serviceUpdateName: String?
        /// The status of the service update
        public let status: ServiceUpdateStatus?

        public init(serviceUpdateName: String? = nil, status: ServiceUpdateStatus? = nil) {
            self.serviceUpdateName = serviceUpdateName
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
        }
    }

    public struct PurchaseReservedNodesOfferingRequest: AWSEncodableShape {
        /// The number of node instances to reserve.
        public let nodeCount: Int?
        /// A customer-specified identifier to track this reservation.
        public let reservationId: String?
        /// The ID of the reserved node offering to purchase.
        public let reservedNodesOfferingId: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        public init(nodeCount: Int? = nil, reservationId: String? = nil, reservedNodesOfferingId: String, tags: [Tag]? = nil) {
            self.nodeCount = nodeCount
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case nodeCount = "NodeCount"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
            case tags = "Tags"
        }
    }

    public struct PurchaseReservedNodesOfferingResponse: AWSDecodableShape {
        /// Represents the output of a PurchaseReservedNodesOffering operation.
        public let reservedNode: ReservedNode?

        public init(reservedNode: ReservedNode? = nil) {
            self.reservedNode = reservedNode
        }

        private enum CodingKeys: String, CodingKey {
            case reservedNode = "ReservedNode"
        }
    }

    public struct RecurringCharge: AWSDecodableShape {
        /// The amount of the recurring charge to run this reserved node.
        public let recurringChargeAmount: Double?
        /// The frequency of the recurring price charged to run this reserved node.
        public let recurringChargeFrequency: String?

        public init(recurringChargeAmount: Double? = nil, recurringChargeFrequency: String? = nil) {
            self.recurringChargeAmount = recurringChargeAmount
            self.recurringChargeFrequency = recurringChargeFrequency
        }

        private enum CodingKeys: String, CodingKey {
            case recurringChargeAmount = "RecurringChargeAmount"
            case recurringChargeFrequency = "RecurringChargeFrequency"
        }
    }

    public struct ReplicaConfigurationRequest: AWSEncodableShape {
        /// The number of replicas to scale up or down to
        public let replicaCount: Int?

        public init(replicaCount: Int? = nil) {
            self.replicaCount = replicaCount
        }

        private enum CodingKeys: String, CodingKey {
            case replicaCount = "ReplicaCount"
        }
    }

    public struct ReservedNode: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the reserved node.
        public let arn: String?
        /// The duration of the reservation in seconds.
        public let duration: Int?
        /// The fixed price charged for this reserved node.
        public let fixedPrice: Double?
        /// The number of nodes that have been reserved.
        public let nodeCount: Int?
        /// The node type for the reserved nodes.
        public let nodeType: String?
        /// The offering type of this reserved node.
        public let offeringType: String?
        /// The recurring price charged to run this reserved node.
        public let recurringCharges: [RecurringCharge]?
        /// A customer-specified identifier to track this reservation.
        public let reservationId: String?
        /// The ID of the reserved node offering to purchase.
        public let reservedNodesOfferingId: String?
        /// The time the reservation started.
        public let startTime: Date?
        /// The state of the reserved node.
        public let state: String?

        public init(arn: String? = nil, duration: Int? = nil, fixedPrice: Double? = nil, nodeCount: Int? = nil, nodeType: String? = nil, offeringType: String? = nil, recurringCharges: [RecurringCharge]? = nil, reservationId: String? = nil, reservedNodesOfferingId: String? = nil, startTime: Date? = nil, state: String? = nil) {
            self.arn = arn
            self.duration = duration
            self.fixedPrice = fixedPrice
            self.nodeCount = nodeCount
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.recurringCharges = recurringCharges
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
            self.startTime = startTime
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case duration = "Duration"
            case fixedPrice = "FixedPrice"
            case nodeCount = "NodeCount"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case recurringCharges = "RecurringCharges"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
            case startTime = "StartTime"
            case state = "State"
        }
    }

    public struct ReservedNodesOffering: AWSDecodableShape {
        /// The duration of the reservation in seconds.
        public let duration: Int?
        /// The fixed price charged for this reserved node.
        public let fixedPrice: Double?
        /// The node type for the reserved nodes. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type of this reserved node.
        public let offeringType: String?
        /// The recurring price charged to run this reserved node.
        public let recurringCharges: [RecurringCharge]?
        /// The offering identifier.
        public let reservedNodesOfferingId: String?

        public init(duration: Int? = nil, fixedPrice: Double? = nil, nodeType: String? = nil, offeringType: String? = nil, recurringCharges: [RecurringCharge]? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.fixedPrice = fixedPrice
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.recurringCharges = recurringCharges
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case fixedPrice = "FixedPrice"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case recurringCharges = "RecurringCharges"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct ResetParameterGroupRequest: AWSEncodableShape {
        /// If true, all parameters in the parameter group are reset to their default values. If false, only the parameters listed by ParameterNames are reset to their default values.
        public let allParameters: Bool?
        /// The name of the parameter group to reset.
        public let parameterGroupName: String
        /// An array of parameter names to reset to their default values. If AllParameters is true, do not use ParameterNames. If AllParameters is false, you must specify the name of at least one parameter to reset.
        public let parameterNames: [String]?

        public init(allParameters: Bool? = nil, parameterGroupName: String, parameterNames: [String]? = nil) {
            self.allParameters = allParameters
            self.parameterGroupName = parameterGroupName
            self.parameterNames = parameterNames
        }

        private enum CodingKeys: String, CodingKey {
            case allParameters = "AllParameters"
            case parameterGroupName = "ParameterGroupName"
            case parameterNames = "ParameterNames"
        }
    }

    public struct ResetParameterGroupResponse: AWSDecodableShape {
        /// The parameter group being reset.
        public let parameterGroup: ParameterGroup?

        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct ReshardingStatus: AWSDecodableShape {
        /// The status of the online resharding slot migration
        public let slotMigration: SlotMigration?

        public init(slotMigration: SlotMigration? = nil) {
            self.slotMigration = slotMigration
        }

        private enum CodingKeys: String, CodingKey {
            case slotMigration = "SlotMigration"
        }
    }

    public struct SecurityGroupMembership: AWSDecodableShape {
        /// The identifier of the security group.
        public let securityGroupId: String?
        /// The status of the security group membership. The status changes whenever a security group is modified, or when the security groups assigned to a cluster are modified.
        public let status: String?

        public init(securityGroupId: String? = nil, status: String? = nil) {
            self.securityGroupId = securityGroupId
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupId = "SecurityGroupId"
            case status = "Status"
        }
    }

    public struct ServiceUpdate: AWSDecodableShape {
        /// The date at which the service update will be automatically applied
        public let autoUpdateStartDate: Date?
        /// The name of the cluster to which the service update applies
        public let clusterName: String?
        /// Provides details of the service update
        public let description: String?
        /// A list of nodes updated by the service update
        public let nodesUpdated: String?
        /// The date when the service update is initially available
        public let releaseDate: Date?
        /// The unique ID of the service update
        public let serviceUpdateName: String?
        /// The status of the service update
        public let status: ServiceUpdateStatus?
        /// Reflects the nature of the service update
        public let type: ServiceUpdateType?

        public init(autoUpdateStartDate: Date? = nil, clusterName: String? = nil, description: String? = nil, nodesUpdated: String? = nil, releaseDate: Date? = nil, serviceUpdateName: String? = nil, status: ServiceUpdateStatus? = nil, type: ServiceUpdateType? = nil) {
            self.autoUpdateStartDate = autoUpdateStartDate
            self.clusterName = clusterName
            self.description = description
            self.nodesUpdated = nodesUpdated
            self.releaseDate = releaseDate
            self.serviceUpdateName = serviceUpdateName
            self.status = status
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case autoUpdateStartDate = "AutoUpdateStartDate"
            case clusterName = "ClusterName"
            case description = "Description"
            case nodesUpdated = "NodesUpdated"
            case releaseDate = "ReleaseDate"
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
            case type = "Type"
        }
    }

    public struct ServiceUpdateRequest: AWSEncodableShape {
        /// The unique ID of the service update
        public let serviceUpdateNameToApply: String?

        public init(serviceUpdateNameToApply: String? = nil) {
            self.serviceUpdateNameToApply = serviceUpdateNameToApply
        }

        private enum CodingKeys: String, CodingKey {
            case serviceUpdateNameToApply = "ServiceUpdateNameToApply"
        }
    }

    public struct Shard: AWSDecodableShape {
        /// The name of the shard
        public let name: String?
        /// A list containing information about individual nodes within the shard
        public let nodes: [Node]?
        /// The number of nodes in the shard
        public let numberOfNodes: Int?
        /// The keyspace for this shard.
        public let slots: String?
        /// The current state of this replication group - creating, available, modifying, deleting.
        public let status: String?

        public init(name: String? = nil, nodes: [Node]? = nil, numberOfNodes: Int? = nil, slots: String? = nil, status: String? = nil) {
            self.name = name
            self.nodes = nodes
            self.numberOfNodes = numberOfNodes
            self.slots = slots
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case nodes = "Nodes"
            case numberOfNodes = "NumberOfNodes"
            case slots = "Slots"
            case status = "Status"
        }
    }

    public struct ShardConfiguration: AWSDecodableShape {
        /// The number of read replica nodes in this shard.
        public let replicaCount: Int?
        /// A string that specifies the keyspace for a particular node group. Keyspaces range from 0 to 16,383. The string is in the format startkey-endkey.
        public let slots: String?

        public init(replicaCount: Int? = nil, slots: String? = nil) {
            self.replicaCount = replicaCount
            self.slots = slots
        }

        private enum CodingKeys: String, CodingKey {
            case replicaCount = "ReplicaCount"
            case slots = "Slots"
        }
    }

    public struct ShardConfigurationRequest: AWSEncodableShape {
        /// The number of shards in the cluster
        public let shardCount: Int?

        public init(shardCount: Int? = nil) {
            self.shardCount = shardCount
        }

        private enum CodingKeys: String, CodingKey {
            case shardCount = "ShardCount"
        }
    }

    public struct ShardDetail: AWSDecodableShape {
        /// The configuration details of the shard
        public let configuration: ShardConfiguration?
        /// The name of the shard
        public let name: String?
        /// The size of the shard's snapshot
        public let size: String?
        /// The date and time that the shard's snapshot was created
        public let snapshotCreationTime: Date?

        public init(configuration: ShardConfiguration? = nil, name: String? = nil, size: String? = nil, snapshotCreationTime: Date? = nil) {
            self.configuration = configuration
            self.name = name
            self.size = size
            self.snapshotCreationTime = snapshotCreationTime
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "Configuration"
            case name = "Name"
            case size = "Size"
            case snapshotCreationTime = "SnapshotCreationTime"
        }
    }

    public struct SlotMigration: AWSDecodableShape {
        /// The percentage of the slot migration that is complete.
        public let progressPercentage: Double?

        public init(progressPercentage: Double? = nil) {
            self.progressPercentage = progressPercentage
        }

        private enum CodingKeys: String, CodingKey {
            case progressPercentage = "ProgressPercentage"
        }
    }

    public struct Snapshot: AWSDecodableShape {
        /// The ARN (Amazon Resource Name) of the snapshot.
        public let arn: String?
        /// The configuration of the cluster from which the snapshot was taken
        public let clusterConfiguration: ClusterConfiguration?
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: DataTieringStatus?
        /// The ID of the KMS key used to encrypt the snapshot.
        public let kmsKeyId: String?
        /// The name of the snapshot
        public let name: String?
        /// Indicates whether the snapshot is from an automatic backup (automated) or was created manually (manual).
        public let source: String?
        /// The status of the snapshot. Valid values: creating | available | restoring | copying | deleting.
        public let status: String?

        public init(arn: String? = nil, clusterConfiguration: ClusterConfiguration? = nil, dataTiering: DataTieringStatus? = nil, kmsKeyId: String? = nil, name: String? = nil, source: String? = nil, status: String? = nil) {
            self.arn = arn
            self.clusterConfiguration = clusterConfiguration
            self.dataTiering = dataTiering
            self.kmsKeyId = kmsKeyId
            self.name = name
            self.source = source
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusterConfiguration = "ClusterConfiguration"
            case dataTiering = "DataTiering"
            case kmsKeyId = "KmsKeyId"
            case name = "Name"
            case source = "Source"
            case status = "Status"
        }
    }

    public struct Subnet: AWSDecodableShape {
        /// The Availability Zone where the subnet resides
        public let availabilityZone: AvailabilityZone?
        /// The unique identifier for the subnet.
        public let identifier: String?

        public init(availabilityZone: AvailabilityZone? = nil, identifier: String? = nil) {
            self.availabilityZone = availabilityZone
            self.identifier = identifier
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case identifier = "Identifier"
        }
    }

    public struct SubnetGroup: AWSDecodableShape {
        /// The ARN (Amazon Resource Name) of the subnet group.
        public let arn: String?
        /// A description of the subnet group
        public let description: String?
        /// The name of the subnet group
        public let name: String?
        /// A list of subnets associated with the subnet group.
        public let subnets: [Subnet]?
        /// The Amazon Virtual Private Cloud identifier (VPC ID) of the subnet group.
        public let vpcId: String?

        public init(arn: String? = nil, description: String? = nil, name: String? = nil, subnets: [Subnet]? = nil, vpcId: String? = nil) {
            self.arn = arn
            self.description = description
            self.name = name
            self.subnets = subnets
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case description = "Description"
            case name = "Name"
            case subnets = "Subnets"
            case vpcId = "VpcId"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key for the tag. May not be null.
        public let key: String?
        /// The tag's value. May be null.
        public let value: String?

        public init(key: String? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to which the tags are to be added
        public let resourceArn: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]

        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        /// A list of tags as key-value pairs.
        public let tagList: [Tag]?

        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct UnprocessedCluster: AWSDecodableShape {
        /// The name of the cluster
        public let clusterName: String?
        /// The error message associated with the update failure
        public let errorMessage: String?
        /// The error type associated with the update failure
        public let errorType: String?

        public init(clusterName: String? = nil, errorMessage: String? = nil, errorType: String? = nil) {
            self.clusterName = clusterName
            self.errorMessage = errorMessage
            self.errorType = errorType
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case errorMessage = "ErrorMessage"
            case errorType = "ErrorType"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to which the tags are to be removed
        public let resourceArn: String
        /// The list of keys of the tags that are to be removed
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        /// The list of tags removed
        public let tagList: [Tag]?

        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct UpdateACLRequest: AWSEncodableShape {
        /// The name of the Access Control List
        public let aclName: String
        /// The list of users to add to the Access Control List
        public let userNamesToAdd: [String]?
        /// The list of users to remove from the Access Control List
        public let userNamesToRemove: [String]?

        public init(aclName: String, userNamesToAdd: [String]? = nil, userNamesToRemove: [String]? = nil) {
            self.aclName = aclName
            self.userNamesToAdd = userNamesToAdd
            self.userNamesToRemove = userNamesToRemove
        }

        public func validate(name: String) throws {
            try self.userNamesToAdd?.forEach {
                try validate($0, name: "userNamesToAdd[]", parent: name, min: 1)
                try validate($0, name: "userNamesToAdd[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNamesToAdd, name: "userNamesToAdd", parent: name, min: 1)
            try self.userNamesToRemove?.forEach {
                try validate($0, name: "userNamesToRemove[]", parent: name, min: 1)
                try validate($0, name: "userNamesToRemove[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNamesToRemove, name: "userNamesToRemove", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case userNamesToAdd = "UserNamesToAdd"
            case userNamesToRemove = "UserNamesToRemove"
        }
    }

    public struct UpdateACLResponse: AWSDecodableShape {
        /// The updated Access Control List
        public let acl: ACL?

        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct UpdateClusterRequest: AWSEncodableShape {
        /// The Access Control List that is associated with the cluster
        public let aclName: String?
        /// The name of the cluster to update
        public let clusterName: String
        /// The description of the cluster to update
        public let description: String?
        /// The upgraded version of the engine to be run on the nodes. You can upgrade to a newer engine version, but you cannot downgrade to an earlier engine version. If you want to use an earlier engine version, you must delete the existing cluster and create it anew with the earlier engine version.
        public let engineVersion: String?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:    sun     mon     tue     wed     thu     fri     sat    Example: sun:23:00-mon:01:30
        public let maintenanceWindow: String?
        /// A valid node type that you want to scale this cluster up or down to.
        public let nodeType: String?
        /// The name of the parameter group to update
        public let parameterGroupName: String?
        /// The number of replicas that will reside in each shard
        public let replicaConfiguration: ReplicaConfigurationRequest?
        /// The SecurityGroupIds to update
        public let securityGroupIds: [String]?
        /// The number of shards in the cluster
        public let shardConfiguration: ShardConfigurationRequest?
        /// The number of days for which MemoryDB retains automatic cluster snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your cluster.
        public let snapshotWindow: String?
        /// The SNS topic ARN to update
        public let snsTopicArn: String?
        /// The status of the Amazon SNS notification topic. Notifications are sent only if the status is active.
        public let snsTopicStatus: String?

        public init(aclName: String? = nil, clusterName: String, description: String? = nil, engineVersion: String? = nil, maintenanceWindow: String? = nil, nodeType: String? = nil, parameterGroupName: String? = nil, replicaConfiguration: ReplicaConfigurationRequest? = nil, securityGroupIds: [String]? = nil, shardConfiguration: ShardConfigurationRequest? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, snsTopicStatus: String? = nil) {
            self.aclName = aclName
            self.clusterName = clusterName
            self.description = description
            self.engineVersion = engineVersion
            self.maintenanceWindow = maintenanceWindow
            self.nodeType = nodeType
            self.parameterGroupName = parameterGroupName
            self.replicaConfiguration = replicaConfiguration
            self.securityGroupIds = securityGroupIds
            self.shardConfiguration = shardConfiguration
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.snsTopicStatus = snsTopicStatus
        }

        public func validate(name: String) throws {
            try self.validate(self.aclName, name: "aclName", parent: name, min: 1)
            try self.validate(self.aclName, name: "aclName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case clusterName = "ClusterName"
            case description = "Description"
            case engineVersion = "EngineVersion"
            case maintenanceWindow = "MaintenanceWindow"
            case nodeType = "NodeType"
            case parameterGroupName = "ParameterGroupName"
            case replicaConfiguration = "ReplicaConfiguration"
            case securityGroupIds = "SecurityGroupIds"
            case shardConfiguration = "ShardConfiguration"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case snsTopicStatus = "SnsTopicStatus"
        }
    }

    public struct UpdateClusterResponse: AWSDecodableShape {
        /// The updated cluster
        public let cluster: Cluster?

        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct UpdateParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group to update.
        public let parameterGroupName: String
        /// An array of parameter names and values for the parameter update. You must supply at least one parameter name and value; subsequent arguments are optional. A maximum of 20 parameters may be updated per request.
        public let parameterNameValues: [ParameterNameValue]

        public init(parameterGroupName: String, parameterNameValues: [ParameterNameValue]) {
            self.parameterGroupName = parameterGroupName
            self.parameterNameValues = parameterNameValues
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
            case parameterNameValues = "ParameterNameValues"
        }
    }

    public struct UpdateParameterGroupResponse: AWSDecodableShape {
        /// The updated parameter group
        public let parameterGroup: ParameterGroup?

        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct UpdateSubnetGroupRequest: AWSEncodableShape {
        /// A description of the subnet group
        public let description: String?
        /// The name of the subnet group
        public let subnetGroupName: String
        /// The EC2 subnet IDs for the subnet group.
        public let subnetIds: [String]?

        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String]? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
        }
    }

    public struct UpdateSubnetGroupResponse: AWSDecodableShape {
        /// The updated subnet group
        public let subnetGroup: SubnetGroup?

        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct UpdateUserRequest: AWSEncodableShape {
        /// Access permissions string used for this user.
        public let accessString: String?
        /// Denotes the user's authentication properties, such as whether it requires a password to authenticate.
        public let authenticationMode: AuthenticationMode?
        /// The name of the user
        public let userName: String

        public init(accessString: String? = nil, authenticationMode: AuthenticationMode? = nil, userName: String) {
            self.accessString = accessString
            self.authenticationMode = authenticationMode
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.accessString, name: "accessString", parent: name, pattern: "\\S")
            try self.authenticationMode?.validate(name: "\(name).authenticationMode")
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case authenticationMode = "AuthenticationMode"
            case userName = "UserName"
        }
    }

    public struct UpdateUserResponse: AWSDecodableShape {
        /// The updated user
        public let user: User?

        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct User: AWSDecodableShape {
        /// Access permissions string used for this user.
        public let accessString: String?
        /// The names of the Access Control Lists to which the user belongs
        public let aclNames: [String]?
        /// The Amazon Resource Name (ARN) of the user.
        public let arn: String?
        /// Denotes whether the user requires a password to authenticate.
        public let authentication: Authentication?
        /// The minimum engine version supported for the user
        public let minimumEngineVersion: String?
        /// The name of the user
        public let name: String?
        /// Indicates the user status. Can be "active", "modifying" or "deleting".
        public let status: String?

        public init(accessString: String? = nil, aclNames: [String]? = nil, arn: String? = nil, authentication: Authentication? = nil, minimumEngineVersion: String? = nil, name: String? = nil, status: String? = nil) {
            self.accessString = accessString
            self.aclNames = aclNames
            self.arn = arn
            self.authentication = authentication
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case aclNames = "ACLNames"
            case arn = "ARN"
            case authentication = "Authentication"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case status = "Status"
        }
    }
}

// MARK: - Errors

/// Error enum for MemoryDB
public struct MemoryDBErrorType: AWSErrorType {
    enum Code: String {
        case aclAlreadyExistsFault = "ACLAlreadyExistsFault"
        case aclNotFoundFault = "ACLNotFoundFault"
        case aclQuotaExceededFault = "ACLQuotaExceededFault"
        case apiCallRateForCustomerExceededFault = "APICallRateForCustomerExceededFault"
        case clusterAlreadyExistsFault = "ClusterAlreadyExistsFault"
        case clusterNotFoundFault = "ClusterNotFoundFault"
        case clusterQuotaForCustomerExceededFault = "ClusterQuotaForCustomerExceededFault"
        case defaultUserRequired = "DefaultUserRequired"
        case duplicateUserNameFault = "DuplicateUserNameFault"
        case insufficientClusterCapacityFault = "InsufficientClusterCapacityFault"
        case invalidACLStateFault = "InvalidACLStateFault"
        case invalidARNFault = "InvalidARNFault"
        case invalidClusterStateFault = "InvalidClusterStateFault"
        case invalidCredentialsException = "InvalidCredentialsException"
        case invalidKMSKeyFault = "InvalidKMSKeyFault"
        case invalidNodeStateFault = "InvalidNodeStateFault"
        case invalidParameterCombinationException = "InvalidParameterCombinationException"
        case invalidParameterGroupStateFault = "InvalidParameterGroupStateFault"
        case invalidParameterValueException = "InvalidParameterValueException"
        case invalidSnapshotStateFault = "InvalidSnapshotStateFault"
        case invalidSubnet = "InvalidSubnet"
        case invalidUserStateFault = "InvalidUserStateFault"
        case invalidVPCNetworkStateFault = "InvalidVPCNetworkStateFault"
        case noOperationFault = "NoOperationFault"
        case nodeQuotaForClusterExceededFault = "NodeQuotaForClusterExceededFault"
        case nodeQuotaForCustomerExceededFault = "NodeQuotaForCustomerExceededFault"
        case parameterGroupAlreadyExistsFault = "ParameterGroupAlreadyExistsFault"
        case parameterGroupNotFoundFault = "ParameterGroupNotFoundFault"
        case parameterGroupQuotaExceededFault = "ParameterGroupQuotaExceededFault"
        case reservedNodeAlreadyExistsFault = "ReservedNodeAlreadyExistsFault"
        case reservedNodeNotFoundFault = "ReservedNodeNotFoundFault"
        case reservedNodeQuotaExceededFault = "ReservedNodeQuotaExceededFault"
        case reservedNodesOfferingNotFoundFault = "ReservedNodesOfferingNotFoundFault"
        case serviceLinkedRoleNotFoundFault = "ServiceLinkedRoleNotFoundFault"
        case serviceUpdateNotFoundFault = "ServiceUpdateNotFoundFault"
        case shardNotFoundFault = "ShardNotFoundFault"
        case shardsPerClusterQuotaExceededFault = "ShardsPerClusterQuotaExceededFault"
        case snapshotAlreadyExistsFault = "SnapshotAlreadyExistsFault"
        case snapshotNotFoundFault = "SnapshotNotFoundFault"
        case snapshotQuotaExceededFault = "SnapshotQuotaExceededFault"
        case subnetGroupAlreadyExistsFault = "SubnetGroupAlreadyExistsFault"
        case subnetGroupInUseFault = "SubnetGroupInUseFault"
        case subnetGroupNotFoundFault = "SubnetGroupNotFoundFault"
        case subnetGroupQuotaExceededFault = "SubnetGroupQuotaExceededFault"
        case subnetInUse = "SubnetInUse"
        case subnetNotAllowedFault = "SubnetNotAllowedFault"
        case subnetQuotaExceededFault = "SubnetQuotaExceededFault"
        case tagNotFoundFault = "TagNotFoundFault"
        case tagQuotaPerResourceExceeded = "TagQuotaPerResourceExceeded"
        case testFailoverNotAvailableFault = "TestFailoverNotAvailableFault"
        case userAlreadyExistsFault = "UserAlreadyExistsFault"
        case userNotFoundFault = "UserNotFoundFault"
        case userQuotaExceededFault = "UserQuotaExceededFault"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize MemoryDB
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var aclAlreadyExistsFault: Self { .init(.aclAlreadyExistsFault) }
    public static var aclNotFoundFault: Self { .init(.aclNotFoundFault) }
    public static var aclQuotaExceededFault: Self { .init(.aclQuotaExceededFault) }
    public static var apiCallRateForCustomerExceededFault: Self { .init(.apiCallRateForCustomerExceededFault) }
    public static var clusterAlreadyExistsFault: Self { .init(.clusterAlreadyExistsFault) }
    public static var clusterNotFoundFault: Self { .init(.clusterNotFoundFault) }
    public static var clusterQuotaForCustomerExceededFault: Self { .init(.clusterQuotaForCustomerExceededFault) }
    public static var defaultUserRequired: Self { .init(.defaultUserRequired) }
    public static var duplicateUserNameFault: Self { .init(.duplicateUserNameFault) }
    public static var insufficientClusterCapacityFault: Self { .init(.insufficientClusterCapacityFault) }
    public static var invalidACLStateFault: Self { .init(.invalidACLStateFault) }
    public static var invalidARNFault: Self { .init(.invalidARNFault) }
    public static var invalidClusterStateFault: Self { .init(.invalidClusterStateFault) }
    public static var invalidCredentialsException: Self { .init(.invalidCredentialsException) }
    public static var invalidKMSKeyFault: Self { .init(.invalidKMSKeyFault) }
    public static var invalidNodeStateFault: Self { .init(.invalidNodeStateFault) }
    public static var invalidParameterCombinationException: Self { .init(.invalidParameterCombinationException) }
    public static var invalidParameterGroupStateFault: Self { .init(.invalidParameterGroupStateFault) }
    public static var invalidParameterValueException: Self { .init(.invalidParameterValueException) }
    public static var invalidSnapshotStateFault: Self { .init(.invalidSnapshotStateFault) }
    public static var invalidSubnet: Self { .init(.invalidSubnet) }
    public static var invalidUserStateFault: Self { .init(.invalidUserStateFault) }
    public static var invalidVPCNetworkStateFault: Self { .init(.invalidVPCNetworkStateFault) }
    public static var noOperationFault: Self { .init(.noOperationFault) }
    public static var nodeQuotaForClusterExceededFault: Self { .init(.nodeQuotaForClusterExceededFault) }
    public static var nodeQuotaForCustomerExceededFault: Self { .init(.nodeQuotaForCustomerExceededFault) }
    public static var parameterGroupAlreadyExistsFault: Self { .init(.parameterGroupAlreadyExistsFault) }
    public static var parameterGroupNotFoundFault: Self { .init(.parameterGroupNotFoundFault) }
    public static var parameterGroupQuotaExceededFault: Self { .init(.parameterGroupQuotaExceededFault) }
    /// You already have a reservation with the given identifier.
    public static var reservedNodeAlreadyExistsFault: Self { .init(.reservedNodeAlreadyExistsFault) }
    /// The requested node does not exist.
    public static var reservedNodeNotFoundFault: Self { .init(.reservedNodeNotFoundFault) }
    /// The request cannot be processed because it would exceed the user&#39;s node quota.
    public static var reservedNodeQuotaExceededFault: Self { .init(.reservedNodeQuotaExceededFault) }
    /// The requested node offering does not exist.
    public static var reservedNodesOfferingNotFoundFault: Self { .init(.reservedNodesOfferingNotFoundFault) }
    public static var serviceLinkedRoleNotFoundFault: Self { .init(.serviceLinkedRoleNotFoundFault) }
    public static var serviceUpdateNotFoundFault: Self { .init(.serviceUpdateNotFoundFault) }
    public static var shardNotFoundFault: Self { .init(.shardNotFoundFault) }
    public static var shardsPerClusterQuotaExceededFault: Self { .init(.shardsPerClusterQuotaExceededFault) }
    public static var snapshotAlreadyExistsFault: Self { .init(.snapshotAlreadyExistsFault) }
    public static var snapshotNotFoundFault: Self { .init(.snapshotNotFoundFault) }
    public static var snapshotQuotaExceededFault: Self { .init(.snapshotQuotaExceededFault) }
    public static var subnetGroupAlreadyExistsFault: Self { .init(.subnetGroupAlreadyExistsFault) }
    public static var subnetGroupInUseFault: Self { .init(.subnetGroupInUseFault) }
    public static var subnetGroupNotFoundFault: Self { .init(.subnetGroupNotFoundFault) }
    public static var subnetGroupQuotaExceededFault: Self { .init(.subnetGroupQuotaExceededFault) }
    public static var subnetInUse: Self { .init(.subnetInUse) }
    public static var subnetNotAllowedFault: Self { .init(.subnetNotAllowedFault) }
    public static var subnetQuotaExceededFault: Self { .init(.subnetQuotaExceededFault) }
    public static var tagNotFoundFault: Self { .init(.tagNotFoundFault) }
    public static var tagQuotaPerResourceExceeded: Self { .init(.tagQuotaPerResourceExceeded) }
    public static var testFailoverNotAvailableFault: Self { .init(.testFailoverNotAvailableFault) }
    public static var userAlreadyExistsFault: Self { .init(.userAlreadyExistsFault) }
    public static var userNotFoundFault: Self { .init(.userNotFoundFault) }
    public static var userQuotaExceededFault: Self { .init(.userQuotaExceededFault) }
}

extension MemoryDBErrorType: Equatable {
    public static func == (lhs: MemoryDBErrorType, rhs: MemoryDBErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension MemoryDBErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
